package com.tange.ai.iot.client.gnssa.play

import android.Manifest
import android.content.Context
import android.content.Intent
import android.content.pm.ActivityInfo
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.Color
import android.graphics.PorterDuff
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.util.Log
import android.view.*
import android.widget.FrameLayout
import android.widget.SeekBar
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.util.Consumer
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.tange.ai.iot.client.gnssa.R
import com.tange.ai.iot.client.gnssa.databinding.ActivityDevicePlaybackBinding
import com.tange.base.toolkit.*
import com.tange.base.ui.design.BasicDialogRequest
import com.tange.base.ui.design.BasicMenuTextArrow
import com.tange.core.device.facade.DeviceFacade
import com.tange.core.device.facade.Status
import com.tange.core.media.render.DeviceMediaRender
import com.tange.core.media.source.impl.Speed
import com.tange.core.media.source.impl.local.DeviceStoragePlayback
import com.tange.core.media.source.impl.local.DeviceStorageMediaSource
import com.tange.core.trouble.shooting.entry.DebuggingAssistant
//import com.tange.module.media.play.util.BitmapUtil
import com.tg.appcommon.android.TGLog
import java.io.File

class DevicePlaybackActivity : AppCompatActivity() {

    companion object {

        private const val TAG = "DevicePlaybackActivity_"
        private const val PARAM_DEVICE_ID = "PARAM_DEVICE_ID"

        fun launch(context: Context, deviceId: String) {
            context.startActivity(Intent(context, DevicePlaybackActivity::class.java).apply {
                putExtra(PARAM_DEVICE_ID, deviceId)
            })
        }
    }

    private var albumPath = Environment.getExternalStorageDirectory()
        .toString() + File.separator + Environment.DIRECTORY_DCIM

    private lateinit var deviceId: String

    private lateinit var binding: ActivityDevicePlaybackBinding

    private lateinit var deviceFacade: DeviceFacade
    private lateinit var deviceStorageMediaSource: DeviceStorageMediaSource
    private lateinit var deviceMediaRender: DeviceMediaRender

    private var isLandscape = false
    private var rendered = false

    private val playbackIndexList = ArrayList<DeviceStoragePlayback.Index>()
    private var indexRequested = false

    private lateinit var listAdapter: ListAdapter

    private var paused = false

    private var speedPlayEnabled = false

    private var playbackQuery: DeviceStoragePlayback? = null

    private var shouldAutoRequestToday = true

    private var currentVideoStart = 0L
    private var isSeeking = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityDevicePlaybackBinding.inflate(layoutInflater).apply {
            setContentView(root)
            supportActionBar?.hide()
            com.tange.ai.iot.client.gnssa.utils.Utils.setDarkStatusBar(this@DevicePlaybackActivity, Color.TRANSPARENT)
            listAdapter = ListAdapter()
            list.layoutManager = LinearLayoutManager(this@DevicePlaybackActivity, LinearLayoutManager.VERTICAL, false)
            list.adapter = listAdapter
            name.text = "本地录像"
        }

        deviceId = intent.getStringExtra(PARAM_DEVICE_ID)!!

        // 创建设备交互模块
        deviceFacade = DeviceFacade(deviceId).apply {

            // 监听连接状态变化
            observeConnectStatus {
                TGLog.i(TAG, "[connect-status] ${it.status}")
                ui {
                    if (it.status != Status.SUCCESS) {
                        if (it.status == Status.FAILED) {
                            binding.loading.gone()
                            binding.connect.visible()
                            binding.connect.text = "重试"
                            Tips.show("连接失败：$it")
                        } else {
                            binding.loading.visible()
                        }
                    } else {
                        // 设备连接成功后，自动请求 一次 今日录像
                        if (shouldAutoRequestToday) {
                            queryRecordDay()
                            queryRecord(DateUtil.getTodayDate())
                            shouldAutoRequestToday = false
                        }

                        binding.connect.gone()
                        if (rendered) {
                            binding.loading.gone()                        }
                    }
                }
            }
        }

        // 创建 存储卡回放 媒体数据源
        deviceStorageMediaSource = DeviceStorageMediaSource(deviceFacade).apply {
            productionMode = DeviceStorageMediaSource.ProductionMode.SINGLE
            onReceiveNextPart = Consumer {
                Tips.show("开始播放：${DateUtil.getStrToTime(it)}")
            }

        }

        // 创建媒体播放器
        deviceMediaRender = DeviceMediaRender(this, deviceStorageMediaSource).apply {

            // 将播放器示例绑定到UI上
            attach(binding.playerContainer, createCenterLayoutParams())

            // 监听首帧数据渲染回调
            observeFirstFrameRendered {
                Log.i(TAG, "[first-rendered] ")
                rendered = true
                binding.connect.gone()
                binding.loading.gone()
            }

            renderStatusObserver = object : DeviceMediaRender.RenderStatusObserver {

                override fun onStart() {}

                override fun onComplete() {
                    Log.i(TAG, "[RenderStatusObserver] complete.")
                }
            }
        }

        deviceMediaRender.onTimestampUpdate = Consumer {
            binding.playTimestamp.post {
                binding.playTimestamp.text = DateUtil.getStrToTime(it)

                if (currentVideoStart > 0 && !isSeeking) {
                    val process = it - currentVideoStart
                    if (process > 0) {
                        binding.seekbar.progress = process.toInt()
                    }
                }
            }
        }

        binding.seekbar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
            override fun onProgressChanged(
                seekBar: SeekBar?,
                progress: Int,
                fromUser: Boolean,
            ) {
                val playPoint = currentVideoStart + binding.seekbar.progress
                binding.currentProgress.text = "松手以播放 ${playPoint.asTimeWithoutDate()}"
            }

            override fun onStartTrackingTouch(seekBar: SeekBar?) {
                binding.currentProgress.visible()
                isSeeking = true
            }

            override fun onStopTrackingTouch(seekBar: SeekBar?) {
                binding.currentProgress.gone()
                isSeeking = false
                if (currentVideoStart > 0) {
                    val playPoint = currentVideoStart + binding.seekbar.progress
                    seekToTime(playPoint)
                }
            }
        })

        // 初始化调试助手，设置 顶部的 标题 为触发入口
        DebuggingAssistant.attach(this, binding.name).apply {
            deviceId = this@DevicePlaybackActivity.deviceId
        }

        binding.pauseResume.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.baseline_pause_circle_filled_24))
        binding.pauseResume.onClicked { pauseOrResume() }

        binding.loading.visible()
        binding.audio.onClicked { switchAudio() }
        binding.screenShot.onClicked { screenshot() }
        binding.screenRecord.onClicked { screenRecord() }
        binding.fullScreen.onClicked { switchFullScreen() }
        binding.back.onClicked { finish() }
        binding.connect.onClicked { deviceStorageMediaSource.enableProduce(true) }
        binding.speedPlay.onClicked { speedPlay() }

        binding.days.visible()

        binding.day3.text = DateUtil.getTodayDate()
        binding.day3.tag = DateUtil.getTodayDate()

        binding.day1.text = DateUtil.getOldDate(-2)
        binding.day1.tag = DateUtil.getOldDate(-2)

        binding.day2.text = DateUtil.getOldDate(-1)
        binding.day2.tag = DateUtil.getOldDate(-1)


        binding.seekbar.progressDrawable.setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN)
        binding.seekbar.thumb.setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN)

        binding.day3.onClicked {
            queryRecord(it.tag.toString())
//            queryRecord("2025-04-23")
            binding.day1.background = ContextCompat.getDrawable(it.context, R.drawable.day_rounded_bg_not_selected)
            binding.day2.background = ContextCompat.getDrawable(it.context, R.drawable.day_rounded_bg_not_selected)
            binding.day3.background = ContextCompat.getDrawable(it.context, R.drawable.day_rounded_bg_selected)
        }

        binding.day2.onClicked {
            queryRecord(it.tag.toString())
            binding.day1.background = ContextCompat.getDrawable(it.context, R.drawable.day_rounded_bg_not_selected)
            binding.day2.background = ContextCompat.getDrawable(it.context, R.drawable.day_rounded_bg_selected)
            binding.day3.background = ContextCompat.getDrawable(it.context, R.drawable.day_rounded_bg_not_selected)
        }

        binding.day1.onClicked {
            queryRecord(it.tag.toString())
            binding.day1.background = ContextCompat.getDrawable(it.context, R.drawable.day_rounded_bg_selected)
            binding.day2.background = ContextCompat.getDrawable(it.context, R.drawable.day_rounded_bg_not_selected)
            binding.day3.background = ContextCompat.getDrawable(it.context, R.drawable.day_rounded_bg_not_selected)
        }
    }


    // 暂停与恢复播放
    private fun pauseOrResume() {
        if (paused) {
            binding.pauseResume.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.baseline_pause_circle_filled_24))
            deviceStorageMediaSource.resume()
            deviceMediaRender.resume()
        } else {
            binding.pauseResume.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.baseline_play_circle_filled_24))
            deviceStorageMediaSource.pause()
            deviceMediaRender.pause()
        }
        paused = !paused
    }

    private fun speedPlay() {
        if (!speedPlayEnabled) {
            binding.speedPlay.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.baseline_fast_forward_24_enabled))
            deviceStorageMediaSource.setSpeed(Speed.x4)
            Tips.show("已开启 4 倍数播放")
        } else {
            binding.speedPlay.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.baseline_fast_forward_24))
            deviceStorageMediaSource.setSpeed(Speed.x1)
            Tips.show("已恢复 1 倍数播放")
        }

        speedPlayEnabled = !speedPlayEnabled
    }

    private fun seekToTime(playPoint: Long) {
        deviceStorageMediaSource.seek(playPoint)
        Tips.show("切换到：${playPoint.asTimeWithoutDate()}")
        deviceMediaRender.reset()
    }

    private fun queryRecordDay(){
        // 反复查询不同日期，应当使用同一个实例，而非每次都new一个！
        if (playbackQuery == null) {
            playbackQuery = DeviceStoragePlayback(deviceFacade)
        }
        playbackQuery!!.queryRecordDays {
            if (it.success) {
                it.data?.let { list ->
                    TGLog.i(TAG,"查询录像日期：${list}")
                }
            } else {
                Tips.show("查询录像日期失败：${it.message}")
            }
        }

    }
    private fun queryRecord(date: String) {
        ui {
            // 反复查询不同日期，应当使用同一个实例，而非每次都new一个！
            if (playbackQuery == null) {
                playbackQuery = DeviceStoragePlayback(deviceFacade)
            }

            val start = System.currentTimeMillis()

            playbackQuery?.query(date) {
                ui {
                    binding.loading.gone()
                    if (it.success) {
                        binding.list.scrollToPosition(0)
                        it.data?.let { listAdapter.refresh(it) }

                        BasicDialogRequest(this).apply {
                            setMessage("${it.data?.size?:0} 条，耗时 ${System.currentTimeMillis() - start} ms")
                            setPositiveText("知道了")
                            setPositiveOnClicked {
                                dismiss()
                            }
                        }.show()

                    } else {
                        if (DeviceStoragePlayback.ERROR_NO_RECORD == it.code) {
                            binding.emptyView.visible()
                        } else {
                            binding.emptyView.visible()
                            binding.emptyView.text = "错误：${it.code}, ${it.message}"
                        }
                    }
                }
            }
        }
    }

    override fun onResume() {
        super.onResume()
        Log.i(TAG, "[onResume] ")
        deviceStorageMediaSource.enableProduce(true)
        deviceMediaRender.play(true)
    }

    override fun onPause() {
        super.onPause()
        Log.i(TAG, "[onPause] ")
        deviceStorageMediaSource.enableProduce(false)
        deviceMediaRender.play(false)
    }

    private fun createCenterLayoutParams() = FrameLayout.LayoutParams(
        FrameLayout.LayoutParams.MATCH_PARENT,
        FrameLayout.LayoutParams.MATCH_PARENT
    ).apply { gravity = Gravity.CENTER }

    private fun screenRecord() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_MEDIA_IMAGES) != PackageManager.PERMISSION_GRANTED) {
                this.requestPermissions(arrayOf(Manifest.permission.READ_MEDIA_IMAGES,Manifest.permission.READ_MEDIA_VIDEO), 100)
                Tips.show("需要存储权限")
                return
            }
        } else {
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    this.requestPermissions(arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), 100)
                }
                Tips.show("需要存储权限")
                return
            }
        }

        if (deviceMediaRender.screenRecord().isStarted()) {
            val file = File(albumPath, "TG-${System.currentTimeMillis()}.mp4")
            deviceMediaRender.screenRecord().finish(file.absolutePath) {
                if (it) Tips.show("录屏已保存到 ${file.absolutePath}")
            }
            binding.screenRecord.setImageDrawable(ContextCompat.getDrawable(this,
                R.drawable.ic_baseline_videocam_24
            ))
        } else {
            deviceMediaRender.screenRecord().start()
            binding.screenRecord.setImageDrawable(ContextCompat.getDrawable(this,
                R.drawable.ic_baseline_videocam_off_24
            ))
            Tips.show("开始录屏，再次点击结束录屏")
        }
    }

    private fun switchAudio() {
        if (!deviceMediaRender.muted) {
            binding.audio.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.ic_baseline_volume_off_24))
            deviceMediaRender.mute(true)
        } else {
            binding.audio.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.ic_baseline_volume_on_24))
            deviceMediaRender.mute(false)
        }
    }

    private fun screenshot() {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                this.requestPermissions(arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), 100)
            }
            Tips.show("需要存储权限")
            return
        }

        deviceMediaRender.screenshot()?.let {

            val file = File(albumPath, "TG-${System.currentTimeMillis()}.jpg")

            BitmapUtil.saveBitmapToFile(file, it, Bitmap.CompressFormat.JPEG)

            if (file.exists()) {
                val intent = Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE)
                val uri = Uri.fromFile(file)
                intent.data = uri
                sendBroadcast(intent)
                Tips.show("截图已保存到 ${file.absolutePath}")
            }
        }
    }

    private fun switchFullScreen() {
        if (isLandscape) {
            binding.bottomLayout.visibility = View.VISIBLE
            binding.topBar.visibility = View.VISIBLE
            binding.opButtons.visibility = View.VISIBLE
            requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
            isLandscape = false
        } else {
            binding.bottomLayout.visibility = View.GONE
            binding.topBar.visibility = View.GONE
            binding.opButtons.visibility = View.GONE
            requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
            isLandscape = true
            binding.playerContainer.postDelayed({
                Tips.show("使用物理返回键退出全屏")
            }, 1000)
        }

        binding.playerContainer.post {
            deviceMediaRender.resize()
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        deviceFacade.disconnect()
    }

    override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean =
        if (KeyEvent.KEYCODE_BACK == keyCode) {
            if (isLandscape) {
                switchFullScreen()
                true
            }
            else {
                finish()
                true
            }
        } else super.onKeyDown(keyCode, event)

    fun trsformEventName(eventType: Int): String {
        return when (eventType) {
            DeviceStoragePlayback.Index.EVENT_MOTION_DETECTED -> "移动"
            DeviceStoragePlayback.Index.EVENT_HUMAN_BODY -> "人形"
            DeviceStoragePlayback.Index.EVENT_SOUND -> "声音"
            DeviceStoragePlayback.Index.EVENT_PIR -> "PIR"
            else -> "未知"
        }
    }


    inner class ListAdapter : RecyclerView.Adapter<ViewHolder>() {
        private val apList: MutableList<DeviceStoragePlayback.Index> = java.util.ArrayList()
        fun refresh(list: List<DeviceStoragePlayback.Index>) {
            apList.clear()
            apList.addAll(list)
            notifyDataSetChanged()
        }

        override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
            val view: View = LayoutInflater.from(viewGroup.context)
                .inflate(R.layout.item_device_list, viewGroup, false)
            return ViewHolder(BasicMenuTextArrow(viewGroup.context))
        }

        override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
            val item = apList[position]
            viewHolder.menu.setBackgroundResource(com.tange.base.ui.design.featured.R.drawable.basic_background_filled_round_neutral_10)
            if (item.event > 0) {
                viewHolder.menu.name.text = "${DateUtil.getStrToTime(item.start)} --  ${trsformEventName(item.event)}"
            } else {
                viewHolder.menu.name.text = "${DateUtil.getStrToTime(item.start)}"
            }
            viewHolder.menu.desc.text = "至 ${DateUtil.getStrToTime(item.end)}"
            viewHolder.menu.desc.visible()

            var lp: ViewGroup.LayoutParams? = viewHolder.menu.layoutParams
            if (lp == null) lp = RecyclerView.LayoutParams(RecyclerView.LayoutParams.WRAP_CONTENT, RecyclerView.LayoutParams.WRAP_CONTENT)
            lp?.let {
                if (it is RecyclerView.LayoutParams) {
                    it.bottomMargin = 50
                    viewHolder.menu.layoutParams = it
                }
            }

            viewHolder.itemView.setOnClickListener { view: View? ->
                binding.pauseResume.setImageDrawable(ContextCompat.getDrawable(view?.context!!, R.drawable.baseline_pause_circle_filled_24))
                paused = false

                switchDataSource(item)
                seekToTime(item.start)
            }
        }

        override fun getItemCount(): Int {
            return apList.size
        }
    }

    private fun switchDataSource(item: DeviceStoragePlayback.Index) {

        val start = (item.start ?: 0)
        val end = (item.end ?: 0)
        currentVideoStart = start

        binding.timelineSeekbar.visible()
        binding.seekbar.max = (end - start).toInt()

        binding.timelineStart.text = start.asTimeWithoutDate()
        binding.timelineEnd.text = end.asTimeWithoutDate()
    }

    class ViewHolder(view: BasicMenuTextArrow) : RecyclerView.ViewHolder(view) {
        val menu: BasicMenuTextArrow

        init {
            menu = view
        }
    }
}